package net.oschina.arvin.admin.util;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import net.oschina.arvin.admin.exception.JsonException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;

/**
 * @author Arvin
 * @time 2017/11/20 22:57
 */
public class JsonUtil {

    private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);

    private static ObjectMapper lowerCaseMapper = new ObjectMapper();
    private static ObjectMapper mapper = new ObjectMapper();
    /** 忽略不存在的字段. */
    private static ObjectMapper mapperIgnoreUnknownField = new ObjectMapper();
    private static ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter();

    static {
        mapperIgnoreUnknownField.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        lowerCaseMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        lowerCaseMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapperIgnoreUnknownField.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    }

    /**
     * 将对象转成json.
     *
     * @param obj 对象
     * @return
     */
    public static String toFormatJson(Object obj) {
        try {
            if (null == obj) {
                return null;
            } else {
                return writer.writeValueAsString(obj);
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new JsonException(e.getMessage(), e);
        }
    }

    /**
     * 将对象转成json.
     *
     * @param obj 对象
     * @return
     */
    public static String toJson(Object obj) {
        return toJson(obj, mapper);
    }

    /**
     * 转成JSON，使用自己定义的 mapper
     *
     * @param obj    要转换的对象
     * @param mapper mapper
     * @return
     */
    public static String toJson(Object obj, ObjectMapper mapper) {
        try {
            String json;
            if (obj == null) {
                json = null;
            } else {
                json = mapper.writeValueAsString(obj);
            }
            return json;
        } catch (Exception e) {
            logger.warn(e.getMessage());
            throw new JsonException(e.getMessage(), e);
        }
    }

    /**
     * 将对象转成json,驼峰变下划线 例如userName-->user_name
     *
     * @param obj 要转换的对象
     * @return
     */
    public static String toJsonLowerCase(Object obj) {
        return toJson(obj, lowerCaseMapper);
    }


    /**
     * 将Json转换成对象.
     *
     * @param json  json 字符串
     * @param clazz 要转换的类型
     * @return
     */
    public static <T> T toObject(String json, Class<T> clazz) {
        return toObject(json, clazz, false);
    }

    /**
     * 将Json转换成对象.
     *
     * @param json               json 字符串
     * @param clazz              要转换的类型
     * @param ignoreUnknownField 是否忽略不存在的字段?
     * @return
     */
    public static <T> T toObject(String json, Class<T> clazz, boolean ignoreUnknownField) {
        try {
            if (json == null || json.length() == 0) {
                return null;
            } else {
                if (ignoreUnknownField) {
                    return mapperIgnoreUnknownField.readValue(json, clazz);
                } else {
                    return mapper.readValue(json, clazz);
                }
            }
        } catch (Exception e) {
            logger.warn("message:" + e.getMessage() + " json:" + json);
            throw new JsonException(e.getMessage(), e);
        }
    }
}
